package architecture;
import java.io.*;
//TestMips
public class TestMips{
	Pipeline_Architecture pa;
	void init() throws Exception{
		pa=new Pipeline_Architecture();
		pa.variable_init();
		pa.addForwarding();
		pa.addStall();
		pa.setForwarding(true,true,true);
		pa.instructionMemory.initMem("srcbin.txt");
	}
	void monitor() throws Exception{
		BufferedReader in;
		in=new BufferedReader(new InputStreamReader(System.in));
		String str;
		while(!(str=in.readLine()).equals("q")){
			debuginfo(str);
		}
	}
/*	public static void main(String args[]) throws Exception{
		TestMips mine=new TestMips();
		System.out.println("Test version of MIPS simulator:");
		mine.init();
		System.out.println("Init OK!");
		System.out.println("Please enter debug command!");
		mine.monitor();
	}
	*/
	void helpinfo(String str){
		PrintStream o=System.out;
		o.println("debug command->entity");
		if(str.equals("h:if")){
			o.println("pc->PC");
			o.println("instm->InstructionMemory");
			o.println("pcaddermux->pc_adder_mux");
			o.println("pcadder->pc_adder");
			o.println("ctrlh->controlHazardUnit");
		}
		if(str.equals("h:id")){
			o.println("regs->Registers");
			o.println("signext->signExtend");
			o.println("brchadder->branchAdder");
			o.println("jgzero->judgeZero");
			o.println("zf1->zero_forwarding_mux1");
			o.println("zf2->zero_forwarding_mux2");
			o.println("idf->ID_forwardingUnit");
		}
		if(str.equals("h:ex")){
			o.println("alu->ALU");
			o.println("alumux->alu_mux");
			o.println("alufa->alu_forwardA_mux");
			o.println("alufb->alu_forwardB_mux");
			o.println("wregmux->write_register_mux");
			o.println("exf->EX_forwardingUnit");
		}
		if(str.equals("h:mm")){
			o.println("datam->dataMemory");
			o.println("mmf->MEM_forwardingUnit");
		}
		if(str.equals("h:wb")){
			o.println("wbmux->writeback_mux");
		}
		if(str.equals("h:ifid")){
			o.println("ifidmux->IF_ID_MUX");
			o.println("ifidinst->IF_ID_Instruction");
		}
		if(str.equals("h:idex")){
			o.println("idexrd1->ID_EX_read_data1");
			o.println("idexrd2->ID_EX_read_data2");
			o.println("idexsgn->ID_EX_signExtend");
			o.println("idexregs->ID_EX_RegisterRs");
			o.println("idexregt->ID_EX_RegisterRt");
			o.println("idexregd->ID_EX_RegisterRd");
			o.println("idexctrl->ID_EX_Control_Buffer");
		}
		if(str.equals("h:exmm")){
			
			o.println("exmmctrl->EX_MEM_Control_Buffer");
			o.println("exmmalu->EX_MEM_ALU_result");
			o.println("exmmrdda2->EX_MEM_read_data2");
			o.println("exmmwrreg->EX_MEM_write_register");
		}
		if(str.equals("h:mmwb")){
			o.println("mmwbctrl->MEM_WB_Control_Buffer");
			o.println("mmwbrdda->MEM_WB_read_data");
			o.println("mmwbalu->MEM_WB_ALU_result");
			o.println("mmwbwrreg->MEM_WB_write_register");
		}
	}
	void debuginfo(String str){
		if(str.startsWith("h:")){
			helpinfo(str);
		}
		if(str.equals("pc")){
			pa.pc.dump();
		}
		if(str.equals("instm")){
			pa.instructionMemory.dump();
		}
		if(str.equals("regs")){
			pa.registers.dump();
		}
		if(str.equals("wregmux")){
			pa.write_register_mux.dump();
		}
		if(str.equals("signext")){
			pa.signExtend.dump();
		}
		if(str.equals("alumux")){
			pa.alu_mux.dump();
		}
		if(str.equals("alu")){
			pa.alu.dump();
		}
		if(str.equals("datam")){
			pa.dataMemory.dump();
		}
		if(str.equals("wbmux")){
			pa.writeback_mux.dump();
		}
		if(str.equals("pcadder")){
			pa.pc_adder.dump();
		}
		if(str.equals("brchadder")){
			pa.branch_adder.dump();
		}
		if(str.equals("jgzero")){
			pa.judgeZero.dump();
		}
		if(str.equals("pcaddermux")){
			pa.pc_adder_mux.dump();
		}
		if(str.equals("ifidmux")){
			pa.IF_ID_MUX.dump();
		}
		if(str.equals("ifidinst")){
			pa.IF_ID_inst.dump();
		}
		if(str.equals("idexrd1")){
			pa.ID_EX_read_data1.dump();
		}
		if(str.equals("idexrd2")){
			pa.ID_EX_read_data2.dump();
		}
		if(str.equals("idexsgn")){
			pa.ID_EX_signExtend.dump();
		}
		if(str.equals("idexregs")){
			pa.ID_EX_RegisterRs.dump();
		}
		if(str.equals("idexregt")){
			pa.ID_EX_RegisterRt.dump();
		}
		if(str.equals("idexregd")){
			pa.ID_EX_RegisterRd.dump();
		}
		if(str.equals("idexctrl")){
			pa.ID_EX_Control_Buffer.dump();
		}
		if(str.equals("exmmctrl")){
			pa.EX_MEM_Control_Buffer.dump();
		}
		if(str.equals("mmwbctrl")){
			pa.MEM_WB_Control_Buffer.dump();
		}
		if(str.equals("exmmalu")){
			pa.EX_MEM_ALU_result.dump();
		}
		if(str.equals("exmmrdda2")){
			pa.EX_MEM_read_data2.dump();
		}
		if(str.equals("exmmwrreg")){
			pa.EX_MEM_write_register.dump();
		}
		if(str.equals("mmwbrdda")){
			pa.MEM_WB_read_data.dump();
		}
		if(str.equals("mmwbalu")){
			pa.MEM_WB_ALU_result.dump();
		}
		if(str.equals("mmwbwrreg")){
			pa.MEM_WB_write_register.dump();
		}
		if(str.equals("ctrl")){
			pa.controlUnit.dump();
		}
		if(str.equals("idf")){
			pa.ID_forwardingUnit.dump();
		}
		if(str.equals("exf")){
			pa.EX_forwardingUnit.dump();
		}
		if(str.equals("mmf")){
			pa.MEM_forwardingUnit.dump();
		}
		if(str.equals("alufa")){
			pa.alu_forwardA_mux.dump();
		}
		if(str.equals("alufb")){
			pa.alu_forwardB_mux.dump();
		}
		if(str.equals("dafc")){
			pa.dataMemory_forwardC_mux.dump();
		}
		if(str.equals("zf1")){
			pa.zero_forwardD_mux1.dump();
		}
		if(str.equals("zf2")){
			pa.zero_forwardD_mux2.dump();
		}
		if(str.equals("ctrlh")){
			pa.controlHazardUnit.dump();
		}
		if(str.equals("fs")){
			System.out.println("--------");
			System.out.println("forwardingStatus:");
			System.out.println("id_is_forwarding:"+pa.id_is_forwarding);
			System.out.println("ex_is_forwarding:"+pa.ex_is_forwarding);
			System.out.println("mem_is_forwarding:"+pa.mem_is_forwarding);
			System.out.println("--------");
		}
		if(str.equals("clk")){
			pa.clockEvent();
		}
		if(str.startsWith("setf")){
			String[] strarray=str.split("\\s+");
			if(strarray.length!=4){
				System.out.println("args error!");
				return;
			}
			boolean[] farray=new boolean[3]; 
			for(int i=0;i<farray.length;++i){
				if(strarray[i+1].equals("1")){
					farray[i]=true;
				}
				else farray[i]=false;
			}
			pa.setForwarding(farray[0],farray[1],farray[2]);
		}
		if(str.startsWith("rm")){
			String[] strarray=str.split("\\s+");
			if(strarray.length!=2){
				System.out.println("args error!");
				return;
			}
			System.out.println(pa.instructionMemory.getWord
					(Integer.parseInt(strarray[1])));
		}
		if(str.startsWith("dm")){
			String[] strarray=str.split("\\s+");
			if(strarray.length!=2){
				System.out.println("args error!");
				return;
			}
			System.out.println(pa.dataMemory.getWord
					(Integer.parseInt(strarray[1])));
		}
	}
	
}